package com.wbxqy.car_management_system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wbxqy.car_management_system.dto.TimeSlot;
import com.wbxqy.car_management_system.entity.Car;
import com.wbxqy.car_management_system.entity.CarRequest;
import com.wbxqy.car_management_system.entity.User;
import com.wbxqy.car_management_system.mapper.CarRequestMapper;
import com.wbxqy.car_management_system.mapper.UserMapper;
import com.wbxqy.car_management_system.service.ICarRequestService;
import com.wbxqy.car_management_system.service.ICarService;
import com.wbxqy.car_management_system.service.IUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 * 用车申请表 服务实现类
 * </p>
 *
 * @author wbxqy
 * @since 2024-07-04
 */
@Service
public class CarRequestServiceImpl extends ServiceImpl<CarRequestMapper, CarRequest> implements ICarRequestService {
    @Autowired
    private CarRequestMapper carRequestMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    IUserService userService;
    @Autowired
    private ICarService carService;

    public boolean isDriverFree(int driverId, LocalDateTime startTime, LocalDateTime endTime) {
        List<CarRequest> approvedRequests = carRequestMapper.findApprovedRequestsByDriverId(driverId);
        final User user = userService.getById(driverId);
        if (user.getStatusWbxqy().equals("O")){
            return false;
        }
        if (user.getStatusWbxqy().equals("I")){
            return false;
        }
        for (CarRequest request : approvedRequests) {
            if (request.getStartTimeWbxqy().isBefore(endTime) && request.getEndTimeWbxqy().isAfter(startTime)) {
                return false;
            }
        }

        return true;
    }

    public List<TimeSlot> getDriverBusyTimeSlots(int driverId) {
        List<CarRequest> approvedRequests = carRequestMapper.findApprovedRequestsByDriverId(driverId);

        return approvedRequests.stream()
                .map(request -> new TimeSlot(request.getStartTimeWbxqy(), request.getEndTimeWbxqy()))
                .collect(Collectors.toList());
    }


    /**
     * 获取在指定时间段内有空的所有司机
     *
     * @param startTime
     * @param endTime
     * @return
     */
    public List<User> getFreeDrivers(LocalDateTime startTime, LocalDateTime endTime) {
        // 获取所有司机列表
        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_wbxqy", "S");
        List<User> allDrivers = userService.list(queryWrapper);
        // 过滤出有空的司机
        return allDrivers.stream()
                .filter(driver -> isDriverFree(driver.getUserIdWbxqy(), startTime, endTime))
                .collect(Collectors.toList());
    }

    public boolean isCarFree(int carId, LocalDateTime startTime, LocalDateTime endTime) {
        List<CarRequest> approvedRequests = carRequestMapper.findApprovedRequestsByCarId(carId);
        List<Integer> outCarIds = userMapper.getOutCarIds();

        final Car car = carService.getById(carId);
        if (!car.getStatusWbxqy().equals("F")) return false;
        if (outCarIds.contains(car.getCarIdWbxqy())){
            return false;
        }
        for (CarRequest request : approvedRequests) {
            if (request.getStartTimeWbxqy().isBefore(endTime) && request.getEndTimeWbxqy().isAfter(startTime)) {
                return false;
            }
        }

        return true;
    }

    public List<TimeSlot> getCarBusyTimeSlots(int carId) {
        List<CarRequest> approvedRequests = carRequestMapper.findApprovedRequestsByCarId(carId);

        return approvedRequests.stream()
                .map(request -> new TimeSlot(request.getStartTimeWbxqy(), request.getEndTimeWbxqy()))
                .collect(Collectors.toList());
    }

    @Override
    public List<Car> getFreeCars(LocalDateTime startTime, LocalDateTime endTime) {
        List<Car> allCars = carService.list();
        // 过滤出有空的司机
        return allCars.stream()
                .filter(car -> isCarFree(car.getCarIdWbxqy(), startTime, endTime))
                .collect(Collectors.toList());
    }

    public CarRequest getFullRequest(Integer requestId) {
        CarRequest carRequest = getById(requestId);
        User user = null;
        Car car = null;
        User driver = null;

        if (carRequest.getUserIdWbxqy() != null) {
            user = userService.getById(carRequest.getUserIdWbxqy());
        }
        if (carRequest.getCarIdWbxqy() != null) {
            car = carService.getById(carRequest.getCarIdWbxqy());
        }
        if (carRequest.getDriverIdWbxqy() != null) {
            driver = userService.getById(carRequest.getDriverIdWbxqy());
        }
        carRequest.setUser(user);
        carRequest.setCar(car);
        carRequest.setDriver(driver);
        return carRequest;
    }

    @Override
    public List<CarRequest> getFullRequests(LocalDateTime start, LocalDateTime end) {
        final LambdaQueryWrapper<CarRequest> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.between(CarRequest::getCreateTimeWbxqy, start, end);
        queryWrapper.in(CarRequest::getStatusWbxqy, "A", "R");
        final List<CarRequest> carRequests = carRequestMapper.selectList(queryWrapper);
        final List<CarRequest> carRequests_res = new ArrayList<>();
        for (CarRequest carRequest : carRequests) {
            carRequests_res.add(getFullRequest(carRequest.getRequestIdWbxqy()));
        }
        return carRequests_res;
    }

    /**
     * 根据状态查询完全的用车申请
     * @param status
     * @return
     */
    @Override
    public List<CarRequest> getFullRequestByStatus(String status) {
        final LambdaQueryWrapper<CarRequest> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.in(CarRequest::getStatusWbxqy, status);
        final List<CarRequest> carRequests = carRequestMapper.selectList(queryWrapper);
        final List<CarRequest> carRequests_res = new ArrayList<>();
        for (CarRequest carRequest : carRequests) {
            carRequests_res.add(getFullRequest(carRequest.getRequestIdWbxqy()));
        }
        return carRequests_res;
    }

}
